import { ref, type Ref } from "vue";
import { KujialeParamModel } from "../types/KujialeJsonModels/KujialeParamModel";
import { Loft3DMesh, Part3DMesh } from "../types/DrawingGroups/meshs";
import {
  Group,
  Mesh,
  MeshBasicMaterial,
  Object3D,
  type Object3DEventMap,
} from "three";
import {
  AssemblyProductGroup,
  Product3DGroup,
  Sub3DGroup,
  Base3DGroup
} from "../types/DrawingGroups/groups";
import { scene } from "..";

export function ChangeColors(colors: { [key: string]: string }) {
  scene.children.forEach((g) => {
    if (g instanceof Product3DGroup) {
      ChangeProductColor(g, colors);
    } else if (g instanceof AssemblyProductGroup) {
      ChangeAssemblyProductColor(g, colors);
    }
  });
}

export const GenerateTextureDict = (
  models: KujialeParamModel[],
  dict: { [key: string]: string }
) :void => {
  //遍历方法
  const generateTextureDictFromModels = (
    models: KujialeParamModel[],
    dict: { [key: string]: string },
    count: Ref<number>,
    red: Ref<number>,
    green: Ref<number>,
    blue: Ref<number>
  ) => {
    models.forEach((m) => {
      if (
        m.textureName != undefined &&
        m.textureName != "" &&
        dict[m.textureName] == undefined
      ) {
        dict[m.textureName] = `rgb(${red.value},${green.value},${blue.value})`;
        count.value++;
  
        if (count.value % 3 == 0) {
          red.value += 33;
          if (red.value > 255) {
            red.value = red.value - 255;
          }
        } else if (count.value % 3 == 1) {
          green.value += 33;
          if (green.value > 255) {
            green.value = green.value - 255;
          }
        } else if (count.value % 3 == 2) {
          blue.value += 33;
          if (blue.value > 255) {
            blue.value = blue.value - 255;
          }
        }
      }
  
      m.subModels &&
        generateTextureDictFromModels(m.subModels, dict, count, red, green, blue);
    });
  };

  let red = 36; //36, 172, 242
  let green = 172;
  let blue = 242;
  generateTextureDictFromModels(
    models,
    dict,
    ref<number>(0),
    ref<number>(red),
    ref<number>(green),
    ref<number>(blue)
  );
};



export const GetTextureDictOnGroups = (
  groups: Base3DGroup[]
): { [key: string]: string } => {
  const dict: { [key: string]: string } = {};
  groups.forEach((g) => {
    getTextureDictFromGroup(dict, g);
  });
  return dict;
};

const getTextureDictFromGroup = (
  dict: { [key: string]: string },
  g: Object3D<Object3DEventMap>
) => {
  if (g instanceof Part3DMesh || g instanceof Loft3DMesh) {
    var mesh = g as Mesh;
    var [model] = g.model.kujialeModel!;
    if (model.textureName in dict) {
    } else {
      dict[model.textureName] =
        "#" + (mesh.material as MeshBasicMaterial).color.getHexString();
    }
  } else if (
    g instanceof Product3DGroup ||
    g instanceof Sub3DGroup ||
    g instanceof AssemblyProductGroup
  ) {
    g.children.forEach((gc) => getTextureDictFromGroup(dict, gc));
  }
};

export function ChangeProductColor(
  productGroup: Product3DGroup | Sub3DGroup,
  colorDict: { [key: string]: string }
) {
  productGroup.children.forEach((child) => {
    if (child instanceof Part3DMesh || child instanceof Loft3DMesh) {
      var [json] = child.model.kujialeModel!;
      if (json.textureName in colorDict) {
        (child.material as MeshBasicMaterial).color.set(
          colorDict[json.textureName]
        );
      }
    } else if (child instanceof Product3DGroup || child instanceof Sub3DGroup) {
      ChangeProductColor(child, colorDict);
    }
  });
}

export function ChangeAssemblyProductColor(
  asProductGroup: AssemblyProductGroup,
  colorDict: { [key: string]: string }
) {
  asProductGroup.children.forEach((g) => {
    if (g instanceof Product3DGroup) {
      ChangeProductColor(g, colorDict);
    }
  });
}
